import { useReducer, useEffect, useMemo, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import PageContainer from '@/components/PageContainer';
import FlexScrollView from '@/components/FlexScrollView';
import { DynamicColors } from '@/utils/DarkMode';
import i18n from 'i18n-js';
import { getItemForPk } from '@/config/product';
import { useDeviceListStore } from '@/hooks';
import { observer } from 'mobx-react-lite';
import { Tabs, ConfigProvider } from '@taroify/core';
import messageModel, { IUserMessageItem } from '@/models/messages';
import { Moment } from 'moment';
import { isSameDevice } from '@/utils';
import { reaction, toJS } from 'mobx';
import { INewDevice } from '@/models/deviceList/deviceCapacity';
import Taro from '@tarojs/taro';
import { unreadCount, compareDeviceMessageList, compareShareMessageList } from './utils'
import NotiTypeText from './components/NotiTypeText';
import UserNotiItem from './components/UserNotiItem';
import NotiItem from './components/NotiItem';
import './index.less';

export interface IDeviceMessageList {
  device: INewDevice;
  content: IUserMessageItem[];
}
export interface IShareMessageList {
  share: IUserMessageItem;
}

interface NotiState {
  tab: number;
  deviceMessageList: IDeviceMessageList[];
  shareMessageList: IShareMessageList[];
}

const initialState: NotiState = {
  tab: 0,
  deviceMessageList: [],
  shareMessageList: [],
};

const NotiCenterScreen = () => {
  const deviceList = useDeviceListStore();

  const getDeviceMessages = useCallback((data: IUserMessageItem[]) => {
    const deviceMessageArr: any[] = [];
    const shareMessageArr: any[] = [];
    if (data && data.length > 0) {
      data.forEach(item => {
        const { mac, pk, noticeType } = item;
        const device = deviceList.data.find(d => isSameDevice(d, { mac, productKey: pk }));
        if (device && noticeType === 1) {
          const deviceMessage = deviceMessageArr.find(i => {
            if (i.device) {
              return isSameDevice(i.device, device);
            }
            return false;
          });
          if (deviceMessage) {
            deviceMessage.content.push(item);
          } else {
            deviceMessageArr.push({ device, content: [item] });
          }
        }
        // 分享消息
        if (noticeType === 4) {
          shareMessageArr.push({ share: item });
        }
      });
    }
    return { deviceMessageList: deviceMessageArr, shareMessageList: shareMessageArr };
  }, [deviceList]);

  const [state, dispatch] = useReducer((oState: NotiState, action: Partial<NotiState>) => ({ ...oState, ...action }), {
    ...initialState, ...getDeviceMessages(messageModel.data),
  });
  const { tab, deviceMessageList, shareMessageList } = state;

  const haveDeviceUnRead = useMemo(
    () => deviceMessageList && deviceMessageList.findIndex(i => unreadCount(i.content) > 0) > -1,
    [deviceMessageList]
  );

  const haveUserUnRead = useMemo(
    () => shareMessageList && shareMessageList.findIndex(i => !i.share.read && i.share.handle === 1) > -1,
    [shareMessageList]
  );

  const getUnReadIndex = useCallback(() => {
    const deviceUnRead = haveDeviceUnRead;
    if (deviceUnRead) return 0;
    const userUnRead = haveUserUnRead;
    if (userUnRead) return 1;
  }, [haveUserUnRead, haveDeviceUnRead]);

  useEffect(() => {
    dispatch({
      tab: getUnReadIndex(),
    });

    const messageReaction = reaction(
      () => messageModel.data,
      data => {
        console.log('messageReaction');
        const { deviceMessageList: oDeviceMessageList, shareMessageList: oShareMessageList } = state;
        const { shareMessageList: nShareMessageList, deviceMessageList: nDeviceMessageList } = getDeviceMessages(data);
        const newState: Partial<NotiState> = {};
        if (compareDeviceMessageList(nDeviceMessageList, oDeviceMessageList)) {
          newState.deviceMessageList = nDeviceMessageList;
        }
        if (compareShareMessageList(nShareMessageList, oShareMessageList)) {
          newState.shareMessageList = nShareMessageList;
        }
        if (Object.keys(newState).length > 0) {
          console.log('更新message state');
          dispatch({ ...newState });
        }
      }
    );

    return () => {
      messageReaction();
    };
  }, []);

  const getMessages = useCallback(() => {
    messageModel.getMessagesByNone();
  }, []);

  const goToDeviceNoti = useCallback((item: IDeviceMessageList) => {
    messageModel.setEditDeviceMessages(item);
    const {
      device: { name, mac, productKey },
    } = item;
    messageModel.readDeviceMessages({productKey, mac})
    let routeName = `/pages/notiCenter/DeviceNotification/index?deviceName=${name}&mac=${mac}&productKey=${productKey}`;
    Taro.navigateTo({ url: routeName });
  }, []);

  const renderDeviceItem = useCallback((item: IDeviceMessageList) => {
    const {
      content,
      device: { name, productKey, sno, groupID },
    } = item;
    const firstItem = content[0];
    const { ctime, title, msgType } = firstItem;

    const productItem = getItemForPk(productKey);
    let deviceIcon = productItem.icon;
    if (groupID && productItem.groupIcon) {
      deviceIcon = productItem.groupIcon;
    }

    return (
      <NotiItem
        onPress={() => goToDeviceNoti(item)}
        image={deviceIcon}
        title={name}
        unreadCount={unreadCount(content)}
        content={<Text><NotiTypeText msgType={msgType} />{title ?? ''}</Text>}
        time={(ctime as Moment).format('YYYY/MM/DD HH:mm')}
        key={sno}
      />
    );
  }, [goToDeviceNoti]);

  return (
    <ConfigProvider theme={{ tabsActiveColor: DynamicColors.tintColor.value }}>
      <PageContainer title={i18n.t('NOTI_CENTER')} className='notiCenter'>
        <Tabs value={tab} style={{ height: '100%', display: 'flex', flexDirection: 'column' }} onChange={(v) => dispatch({ tab: v })}>
          <Tabs.TabPane title={<TabTitle title={i18n.t('DEVICE')} unRead={haveDeviceUnRead} />}>
            <View style={{ height: '100%' }}>
              <FlexScrollView id='device-message-list'>{deviceMessageList.map(renderDeviceItem)}</FlexScrollView>
            </View>
          </Tabs.TabPane>
          <Tabs.TabPane title={<TabTitle title={i18n.t('USERS')} unRead={haveUserUnRead} />}>
            <View style={{ height: '100%' }}>
              <FlexScrollView id='share-message-list'>
                {shareMessageList.map(i => (
                  <UserNotiItem data={i} key={i.share.id} onHandleFinish={getMessages} />
                ))}
              </FlexScrollView>
            </View>
          </Tabs.TabPane>
        </Tabs>
      </PageContainer>
    </ConfigProvider>
  );
};

const TabTitle = ({ title, unRead }) => {
  return (
    <View style={{ display: 'flex' }}>
      {!!unRead && <View style={{ width: 10, marginLeft: 4 }}></View>}
      {title}
      {!!unRead && (
        <View
          style={{
            width: 8,
            height: 8,
            borderRadius: 8,
            backgroundColor: '#e80037',
            marginLeft: 4,
          }}
        />
      )}
    </View>
  );
};

export default observer(NotiCenterScreen);
